package com.tgpms.web.common.controller;

import com.alibaba.fastjson.JSONObject;
import com.tgpms.auth.security.TokenService;
import com.tgpms.common.Base64Util;
import com.tgpms.common.Result;
import com.tgpms.exception.ExceptionExplain;
import com.tgpms.util.Common;
import com.tgpms.util.FTPUtil;
import com.tgpms.web.common.service.FTPService;
import com.tgpms.web.earlierStage.entity.DocUploadEntity;
import com.tgpms.web.earlierStage.service.EalierDocUploadService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.*;

@Api(value = "FTPController", tags = "ftp文件上传接口")
@RestController
@CrossOrigin//此注解解决可能的跨域问题
public class FTPController {

	private final Logger log = LoggerFactory.getLogger(FTPController.class);

	//ftp_url
	@Value("${ftpparam.url}")
	private String url;
	@Value("${ftpparam.port}")
	private Integer port;
	@Value("${ftpparam.username}")
	private String username;
	@Value("${ftpparam.password}")
	private String password;
	@Value("${ftpparam.filepath1}")
	private String filepath1;
	@Value("${ftpparam.filepath2}")
	private String filepath2;
	@Value("${ftpparam.localloadfile}")
	private String localloadfile;

	
	@Autowired
	private FTPService ftpService;
	@Autowired
	private TokenService tokenService;
	@Autowired
	private EalierDocUploadService ealierDocUploadService;

	@ApiOperation(value = "ftp文件上传接口", notes = "ftp文件上传接口", httpMethod = "POST")
	@ApiImplicitParams({@ApiImplicitParam(name = "file", value = "文件", required = true, dataType = "MultipartFile"),
		@ApiImplicitParam(name = "fileProgCode", value = "屏幕编码", required = true, dataType = "String"),
		@ApiImplicitParam(name = "fileCat", value = "文件类型编码", required = true, dataType = "String"),
		@ApiImplicitParam(name = "fileKey", value = "屏幕主键", required = true, dataType = "String"),
		@ApiImplicitParam(name = "fileShowName", value = "文件描述", required = true, dataType = "String"),
		@ApiImplicitParam(name = "screenType", value = "1成本管理2固定资产", required = true, dataType = "Integer")})

	@PostMapping(value = "/ev/ftputil/ftpUpload",headers = "content-type=multipart/form-data")
	public Result ftpUpload(@RequestParam(value = "file", required = true)MultipartFile file,
			@RequestParam(value="fileProgCode",required = true)String fileProgCode,
			@RequestParam(value="fileCat",required = true)String fileCat,
			@RequestParam(value="fileKey",required = true)String fileKey,
			@RequestParam(value="fileShowName",required = true)String fileShowName,
			@RequestParam(value="screenType",required = true)Integer screenType,
			HttpServletRequest request) {
		Result result = new Result();
		try {
			if(fileProgCode.equals("") || fileCat.equals("") ||  fileKey.equals("") || fileShowName.equals("")) {
				result.setMsg(ExceptionExplain.EMPTY_BY_DATA.getExplain());
				result.setSuccess(false);
				return result;
			}
			fileShowName = new String(fileShowName.getBytes("ISO-8859-1"), "UTF-8");
			String filepath = "";
			if(screenType==1) {
				filepath=filepath1;
			}else if(screenType==2) {
				filepath=filepath2;
			}
			//指定存放上传文件的临时目录
	        String fileDir = "/test";
	        File dir = new File(fileDir);

	        //判断目录是否存在，不存在则创建目录
	        if (!dir.exists()){
	            dir.mkdirs();
	        }
			//将上传文件转文件流
			// 获取文件名
			String fileName = file.getOriginalFilename();
			Long fileSize = file.getSize();
			// 获取文件后缀
			String suffix=fileName.substring(fileName.lastIndexOf(".")+1);
			String newfileName = fileProgCode + "_" + Common.fromDateFormat("yyyyMMddHHmmssSSS");
			fileName = newfileName+"."+suffix;
			// 用屏幕名_时间戳作为文件名，防止生成的临时文件重复
			File excelFile = new File(dir.getAbsolutePath()+ File.separator+ fileName);
			file.transferTo(excelFile);
			InputStream inputStream = new FileInputStream(excelFile);
			excelFile.delete();
			//vform插入文件信息
			Map<String, String> map = new HashMap<String, String>();
			map.put("fileProgCode", fileProgCode);
			map.put("fileCat", fileCat);
			map.put("fileKey", fileKey);
			map.put("fileShowName", fileShowName);
			map.put("fileName", fileName);
			map.put("fileSize", fileSize+"");
			map.put("uploadUser", tokenService.getUserName(request));
			Map<String,String> resMap = ftpService.addUploadFileInfo(map);
			if(resMap.get("code").equals("1")) {
				//上传文件
				if(FTPUtil.upload(url, port, username, password, filepath, inputStream, fileName)) {
					resMap = ftpService.updateUploadFileInfo(map);
					if(resMap.get("code").equals("1")) {
						result.setSuccess(true);
						result.setMsg(ExceptionExplain.SUCCESS_BY_INFOS.getExplain());
						result.setData(fileName);
					}else {
						result.setSuccess(false);
						result.setMsg(ExceptionExplain.ERROR_BY_UPDATE.getExplain());
					}
				}else {
					result.setSuccess(false);
					result.setMsg(ExceptionExplain.ERROR_BY_INSERT.getExplain());
				}
			}else {
				result.setSuccess(false);
				result.setMsg(ExceptionExplain.ERROR_BY_INSERT.getExplain());
			}

		} catch (IOException e) {
			e.printStackTrace();
			result.setMsg(ExceptionExplain.ERROR_BY_INSERT.getExplain());
			result.setSuccess(false);
			return  result;
		}
		return result;
	}


	@PostMapping(value = "/ev/ftputil/ftpDown")
	public ResponseEntity<byte[]> ftpDown(@RequestParam(value="fileName",required = true)String fileName,
			@RequestParam(value="screenType",required = true)Integer screenType,HttpServletResponse response) {
		ResponseEntity<byte[]> entity = null;
		InputStream in = null;
		try {
			if(fileName.equals("")) {
				throw new IOException("参数错误");
			}
			String filepath = "";
			if(screenType==1) {
				filepath=filepath1;
			}else if(screenType==2) {
				filepath=filepath2;
			}
			in = FTPUtil.downloadFileForIn(url, port, username, password, filepath, fileName);
			//设置浏览器响应
			HttpHeaders headers = new HttpHeaders();
			headers.setContentDispositionFormData("attachment", fileName);
			headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			HttpStatus status = HttpStatus.OK;
			//返回字节流IOUtils.toByteArray(in)
			entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, status);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(in!=null) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		return entity;
	}


//	@GetMapping(value = "/ftputil/ftpDown")
//	public void ftpDown(@RequestParam(value="fileName",required = true)String fileName,
//			@RequestParam(value="screenType",required = true)Integer screenType,HttpServletResponse response) throws IOException {
//		String filepath = "";
//		if(screenType==1) {
//			filepath=filepath1;
//		}else if(screenType==2) {
//			filepath=filepath2;
//		}
//		BufferedInputStream bis = null;
//		BufferedOutputStream bos = null;
//		try {
//			InputStream in = FTPUtil.downloadFileForIn(url, port, username, password, filepath, fileName);
//			// 设置response参数，可以打开下载页面
//			response.reset();
//			//	    response.setContentType("applicationnd.ms-excel;charset=utf-8");
//			response.setHeader("Content-Disposition", "attachment;filename="
//					+ new String((fileName).getBytes(), "iso-8859-1"));
//			ServletOutputStream out = response.getOutputStream();
//			bis = new BufferedInputStream(in);
//			bos = new BufferedOutputStream(out);
//			byte[] buff = new byte[2048];
//			int bytesRead;
//			while (-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
//				bos.write(buff, 0, bytesRead);
//			}
//			if (bis != null)
//	            bis.close();
//	        if (bos != null)
//	            bos.close();
//		} catch (Exception e) {
//			e.printStackTrace();
//		}
//	}

	@ApiOperation(value = "ftp文件查询接口", notes = "ftp文件查询接口", httpMethod = "POST")
	@PostMapping(value = "/ev/ftputil/lookFile")
	public Result lookFile(@RequestParam(value = "fileKey", required = true) String fileKey,
			@RequestParam(value = "fileProgCode", required = true) String fileProgCode,
			@RequestParam(value = "dataowner", required = false) String dataowner) {
		Result result = new Result();
		List<Map<String,Object>> list = ftpService.getFilelist(fileKey, fileProgCode, dataowner);
		result.setSuccess(true);
		result.setData(list);
		return result;
	}

	@ApiOperation(value = "多图片预览接口",notes="多图片预览接口",httpMethod = "POST")
	@PostMapping(value = "/ev/ftputil/showPictureByid")
	public Result showPictureByid(@RequestParam(value = "fileKey", required = true) String fileKey,
								  @RequestParam(value = "fileProgCode", required = true) String fileProgCode,
								  @RequestParam(value = "screenType",required = true)Integer screenType,
								  @RequestParam(value = "dataowner", required = false) String dataowner){
		Result result = new Result();
		log.info("多图片预览接口接收到的值为:"+fileKey+fileProgCode);
		//获取文件保存路径
		InputStream in = null;
		byte[] data = null;
		try {
			List<JSONObject> fileList = new ArrayList<JSONObject>();
			List<Map<String, Object>> fileListResult = ftpService.getFilelist(fileKey, fileProgCode, dataowner);
			log.info("多图片预览接口查询的文件id集合为:"+fileListResult);
			String filepath = "";
			if(screenType==1) {
				filepath=filepath1;
			}else if(screenType==2) {
				filepath=filepath2;
			}
			if(fileListResult!=null || fileListResult.size()>0) {
				for(Map<String, Object> map: fileListResult) {
					JSONObject json = new JSONObject();
					String fileName = map.get("FILE_NAME").toString();
					String seqNo = map.get("SEQ_NO").toString();
					in = FTPUtil.downloadFileForIn(url, port, username, password, filepath, fileName);
					if(in!=null) {
						data = new byte[in.available()];
						if (data != null) {
							in.read(data);
							String base64str = Base64Util.ByteToBase64(data);
							json.put("docId", seqNo);
							json.put("docName", fileName);
							json.put("image", "data:image/jpeg;base64,"+base64str);
							fileList.add(json);
						}
					}
				}
			}
			result.setSuccess(true);
			result.setMsg(ExceptionExplain.SUCCESS_BY_INFOS.getExplain());
			result.setData(fileList);
		} catch (Exception e) {
			e.printStackTrace();
			result.setMsg(ExceptionExplain.ERROR_BY_INFOS.getExplain());
			result.setSuccess(false);
		} finally {
			try {
				if(in!=null) {
					in.close();        //关闭文件读取流，输出流
				}
			} catch (IOException e) {
				e.printStackTrace();
				result.setMsg(ExceptionExplain.ERROR_BY_INFOS.getExplain());
				result.setSuccess(false);
			}
		}
		return result;
	}
	
	
	@ApiOperation(value = "ftp文件删除接口", notes = "ftp文件删除接口", httpMethod = "DELETE")
	@DeleteMapping(value = "/ev/ftputil/deleteFile")
	public Result deleteFile(@RequestParam(value = "fileKey", required = true)String fileKey,
			@RequestParam(value = "fileProgCode", required = true)String fileProgCode,
			@RequestParam(value = "seqNo", required = true)String seqNo) {
		Result result = new Result();
		Map<String,String> map = ftpService.deleteFile(fileKey, fileProgCode, seqNo);
		if(map.get("code").equals("1")) {
			result.setSuccess(true);
		}else {
			result.setSuccess(false);
		}
		result.setMsg(map.get("info"));
		return result;
	}


	@ApiOperation(value = "文档在线编辑保存替换接口", notes = "文档在线编辑保存替换接口", httpMethod = "POST")
	@PostMapping(value = "/officeutil/fileSaveReplace",headers = "content-type=multipart/form-data")
	public Result fileSaveReplace(@RequestParam(value = "id", required = true) String id,
								  HttpServletRequest request,@RequestParam("EDITFILE") MultipartFile file) {
		String time = Common.nowTimeFomat("yyyyMMddHHmmssSSS");
		log.info(time+"======文档在线编辑保存替换接口开始======");
		Result result = new Result();
		if(Common.isEmpty(id) || Common.isEmpty(file)) {
			result.setSuccess(false);
			result.setMsg(ExceptionExplain.EMPTY_BY_DATA.getExplain());
			return result;
		}
		try {
			DocUploadEntity docUpload = ealierDocUploadService.selDocUploadById(id);
			log.info(time+"======文档在线编辑保存替换接口查询的文档为:"+docUpload.getNewDocName());
			//先看本地是否存在改文件，有则直接替换本地文件
			String fileDir = localloadfile;
			File dir = new File(fileDir);
			if (!dir.exists()){
				dir.mkdirs();
			}
			File excelFile = new File(dir.getAbsolutePath()+ File.separator+ docUpload.getNewDocName());
			if(excelFile.exists()) {
				log.info(time+"======文档在线编辑保存替换接口查询的文档本地已存在======");
				//先删后传
				if(excelFile.delete()) {
					file.transferTo(excelFile);
				}else {
					result.setSuccess(false);
					result.setMsg("文件编辑失败");
					return result;
				}
			}else {
				log.info(time+"======文档在线编辑保存替换接口查询的文档本地不存在======");
				if(FTPUtil.deleteFile(url, port, username, password, docUpload.getFilePath(), docUpload.getNewDocName())) {
					file.transferTo(excelFile);
				}else {
					result.setSuccess(false);
					result.setMsg("文件编辑失败");
					return result;
				}
			}
			result.setMsg("编辑成功");
		} catch (IOException e) {
			log.error(time+"文档在线编辑保存替换接口异常"+e);
			e.printStackTrace();
			result.setSuccess(false);
			result.setMsg(ExceptionExplain.ERROR_BY_INSERT.getExplain());
			return result;
		}
		log.info(time+"======文档在线编辑保存替换接口结束======");
		return result;
	}


	@ApiOperation(value = "文档获取接口", notes = "文档获取接口", httpMethod = "GET")
	@GetMapping(value = "/officeutil/getFile")
	public ResponseEntity<byte[]> getFile(@RequestParam(value = "id", required = true) String id,HttpServletRequest request) throws FileNotFoundException {
		ResponseEntity<byte[]> entity = null;
		InputStream in = null;
		try {
			DocUploadEntity docUpload = ealierDocUploadService.selDocUploadById(id);
			//先从本地文件夹取文件，有则本地下载，无则ftp下载
			String fileDir = localloadfile;
			File dir = new File(fileDir);
			if (!dir.exists()){
				dir.mkdirs();
				in = FTPUtil.downloadFileForIn(url, port, username, password, docUpload.getFilePath(), docUpload.getNewDocName());
			}else {
				File excelFile = new File(dir.getAbsolutePath()+ File.separator+ docUpload.getNewDocName());
				if(excelFile.exists()) {
					in = new FileInputStream(excelFile);
				}else {
					in = FTPUtil.downloadFileForIn(url, port, username, password, docUpload.getFilePath(), docUpload.getNewDocName());
				}
			}
			//设置浏览器响应
			HttpHeaders headers = new HttpHeaders();
			headers.setContentDispositionFormData("attachment", docUpload.getDocName());
			headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
			HttpStatus status = HttpStatus.OK;
			//返回字节流IOUtils.toByteArray(in)
			entity = new ResponseEntity<byte[]>(IOUtils.toByteArray(in), headers, status);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if(in!=null) {
					in.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return entity;
	}

	public ResponseEntity<FileSystemResource> export(File file) {
		if (file == null) {
			return null;
		}
		HttpHeaders headers = new HttpHeaders();
		headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
		headers.add("Content-Disposition", "attachment; filename=" + file.getName());
		headers.add("Pragma", "no-cache");
		headers.add("Expires", "0");
		headers.add("Last-Modified", new Date().toString());
		headers.add("ETag", String.valueOf(System.currentTimeMillis()));
		return ResponseEntity.ok().headers(headers).contentLength(file.length()).contentType(MediaType.parseMediaType("application/octet-stream")).body(new FileSystemResource(file));
	}


}
